#include "ls_little_fs.h"

#define DBG_TAG "LITTLEFS"
#include "ls_trace_common.h"


#define LITTLEFS_FLASH_BLOCK_SIZE  4096
#define LITTLEFS_FLASH_BLOCK_CYCLE 512

#define LITTLEFS_FLASH_SIZE        (0x80000)
#define LITTLEFS_FLASH_BLOCK_COUNT (LITTLEFS_FLASH_SIZE / LITTLEFS_FLASH_BLOCK_SIZE)



#define LITTLEFS_FLASH_SIZE_USER   (0x32000)
#define LITTLEFS_FLASH_BLOCK_COUNT_USER (LITTLEFS_FLASH_SIZE_USER / LITTLEFS_FLASH_BLOCK_SIZE)

static lfs_t lfs_data;
static lfs_t lfs;
/*!< configuration of the filesystem is provided by this struct */
const struct lfs_config fscfg = {
    // block device operations
    .read = lfs_xip_flash_read,
    .prog = lfs_xip_flash_prog,
    .erase = lfs_xip_flash_erase,
    .sync = lfs_xip_flash_sync,

    // block device configuration
    .read_size = 16,
    .prog_size = 16,
    .lookahead_size = 16,
    .cache_size = 16,

    .block_size = LITTLEFS_FLASH_BLOCK_SIZE,
    .block_count = LITTLEFS_FLASH_BLOCK_COUNT,
    .block_cycles = LITTLEFS_FLASH_BLOCK_CYCLE,
};


/*!< configuration of the filesystem is provided by this struct */
const struct lfs_config fscfg_data = {
    // block device operations
    .read = lfs_xip_flash_read_user,
    .prog = lfs_xip_flash_prog_user,
    .erase = lfs_xip_flash_erase_user,
    .sync = lfs_xip_flash_sync_user,

    // block device configuration
    .read_size = 16,
    .prog_size = 16,
    .lookahead_size = 16,
    .cache_size = 16,

    .block_size = LITTLEFS_FLASH_BLOCK_SIZE,
    .block_count = LITTLEFS_FLASH_BLOCK_COUNT_USER,
    .block_cycles = LITTLEFS_FLASH_BLOCK_CYCLE,
};


///
void ls_little_fs_init()
{
	//
    int err = lfs_mount(&lfs, &fscfg);
    // reformat if we can't mount the filesystem
    // this should only happen on the first boot
    if (err) {
        LS_TRACE_ERROR("try to reformat");
        err = lfs_format(&lfs, &fscfg);
        if (err) {
            LS_TRACE_INFO("reformat fail");
            _CALL_ERROR();
        }

        LS_TRACE_INFO("reformat success");
        err = lfs_mount(&lfs, &fscfg);
        if (err) {
            LS_TRACE_INFO("mount fail");
			_CALL_ERROR();
        }
    }

    LS_TRACE_INFO("mount config success");
    //
    err = lfs_mount(&lfs_data, &fscfg_data);
    // reformat if we can't mount the filesystem
    // this should only happen on the first boot
    if (err) {
        LS_TRACE_ERROR("try to reformat");
        err = lfs_format(&lfs_data, &fscfg_data);
        if (err) {
            LS_TRACE_INFO("reformat fail");
            _CALL_ERROR();
        }

        LS_TRACE_INFO("reformat success");
        err = lfs_mount(&lfs_data, &fscfg_data);
        if (err) {
            LS_TRACE_INFO("mount fail");
			_CALL_ERROR();
        }
    }

    LS_TRACE_INFO("mount data success");
}


/// @brief 
/// @return 
lfs_t* ls_get_fs_config()
{
    return &lfs;
}


/// @brief 
/// @return 
lfs_t* ls_get_fs_data()
{
    return &lfs_data;
}